<?php

namespace libs\qoy\Session;

use SessionHandler;
use libs\qoy\Exception\ExceptionInternalServerError;

/**
 * Memcache 对话存储
 * @param array $config 初始化配置
 * @param array $config["host"] memcache主机
 * @param array $config["port"] memcache端口
 * @param array $config["expire"] session有效期
 * @param array $config["timeout"] 连接超时时间（单位：毫秒）
 * @param array $config["persistent"] 长连接
 * @param array $config["session_name"] key前缀
 * @throws ExceptionInternalServerError
 */
class Memcache extends SessionHandler {

    protected $handler = null;
    protected $config = [
        'host' => '127.0.0.1', // memcache主机
        'port' => 11211, // memcache端口
        'expire' => 3600, // session有效期
        'timeout' => 0, // 连接超时时间（单位：毫秒）
        'persistent' => true, // 长连接
        'session_name' => '', // memcache key前缀
    ];

    /**
     * 
     * @param array $config 初始化配置
     * @param array $config["host"] memcache主机
     * @param array $config["port"] memcache端口
     * @param array $config["expire"] session有效期
     * @param array $config["timeout"] 连接超时时间（单位：毫秒）
     * @param array $config["persistent"] 长连接
     * @param array $config["session_name"] key前缀
     * @throws ExceptionInternalServerError
     */
    public function __construct(array $config = []) {
        $this->config = array_merge($this->config, $config);
        // 检测php环境
        if (!extension_loaded('memcached')) {
            throw new ExceptionInternalServerError(ExceptionInternalServerError::SUPPORT_MEMCACHE);
        }
    }
    /**
     * 打开Session
     * @param string    $savePath
     * @param mixed     $sessName
     */
    public function open(str $savePath, $sessName) {

        $this->handler = new \Memcache;
        // 支持集群
        $hosts = explode(',', $this->config['host']);
        $ports = explode(',', $this->config['port']);
        if (empty($ports[0])) {
            $ports[0] = 11211;
        }
        // 建立连接
        foreach ((array) $hosts as $i => $host) {
            $port = isset($ports[$i]) ? $ports[$i] : $ports[0];
            $this->config['timeout'] > 0 ?
                            $this->handler->addServer($host, $port, $this->config['persistent'], 1, $this->config['timeout']) :
                            $this->handler->addServer($host, $port, $this->config['persistent'], 1);
        }
        return true;
    }

    /**
     * 关闭Session
     * @access public
     */
    public function close() {
        $this->gc(ini_get('session.gc_maxlifetime'));
        $this->handler->close();
        $this->handler = null;
        return true;
    }

    /**
     * 读取Session
     * @access public
     * @param string $sessID
     */
    public function read($sessID) {
        return $this->handler->get($this->config['session_name'] . $sessID);
    }

    /**
     * 写入Session
     * @access public
     * @param string    $sessID
     * @param String    $sessData
     */
    public function write($sessID, $sessData) {
        return $this->handler->set($this->config['session_name'] . $sessID, $sessData, 0, $this->config['expire']);
    }

    /**
     * 删除Session
     * @access public
     * @param string $sessID
     */
    public function destroy($sessID) {
        return $this->handler->delete($this->config['session_name'] . $sessID);
    }

    /**
     * Session 垃圾回收
     * @access public
     * @param string $sessMaxLifeTime
     */
    public function gc($sessMaxLifeTime) {
        return true;
    }

}
